/***********************************************************
 * File Name    : SpO2Calibrator.c
 * Description  : 校准血氧
 * Author       : 
 * Create Date  : 
 * Last Modified: 
 * Version      : 
 * Note         : 
 ***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "SpO2Calibrator.h"

// 血氧校准参数
#define MIN_SPO2 90
#define MAX_SPO2 100
#define MAX_CHANGE 2  // 允许的最大变化量

// 全局变量保存上一次的血氧值
static int last_spo2 = -1;
static int zero_count = 0;  // 新增：记录连续0值的计数器

/**
 * 校准血氧值
 * @param raw_spo2 原始血氧值
 * @return 校准后的血氧值
 */
int calibrate_spo2(int raw_spo2) {
    // 新增：检查是否为0值
    if (raw_spo2 == 0) {
        zero_count++;
        // 如果连续三次为0，则重置血氧数据
        if (zero_count >= 3) {
            last_spo2 = -1;  // 重置为初始状态
            zero_count = 0;  // 重置计数器
            return 0;        // 返回0表示清零
        }
        // 前两次为0时仍返回上一次的有效值
        return (last_spo2 == -1) ? (MIN_SPO2 + MAX_SPO2) / 2 : last_spo2;
    } else {
        zero_count = 0;  // 重置计数器
    }

    // 第一次使用时直接使用原始值（如果有效）
    if (last_spo2 == -1) {
        if (raw_spo2 >= MIN_SPO2 && raw_spo2 <= MAX_SPO2) {
            last_spo2 = raw_spo2;
            return raw_spo2;
        } else {
            // 如果第一次的值就无效，返回中值
            last_spo2 = (MIN_SPO2 + MAX_SPO2) / 2;
            return last_spo2;
        }
    }
    
    // 1. 首先确保血氧在有效范围内
    int clamped_spo2 = raw_spo2;
    if (clamped_spo2 < MIN_SPO2) {
        clamped_spo2 = MIN_SPO2;
    } else if (clamped_spo2 > MAX_SPO2) {
        clamped_spo2 = MAX_SPO2;
    }
    
    // 2. 防止突变 - 限制变化幅度
    int delta = clamped_spo2 - last_spo2;
    if (delta > MAX_CHANGE) {
        clamped_spo2 = last_spo2 + MAX_CHANGE;
    } else if (delta < -MAX_CHANGE) {
        clamped_spo2 = last_spo2 - MAX_CHANGE;
    }
    
    // 更新上一次的血氧值
    last_spo2 = clamped_spo2;
    
    return clamped_spo2;
}

/**
 * 重置血氧校准器
 */
void reset_spo2_calibrator() {
    last_spo2 = -1;
    zero_count = 0;
}